home *** CD-ROM | disk | FTP | other *** search
- /*
- * JPEG Convert1.c
- *
- * Copyright (C) 1992, James H. Brunner.
- *
- * This file is part of the "JPEG Convert" program. The JPEG Convert program signature ('Ijgp')
- * and unique file types ('TARG', 'RLE ', 'PPM ') are registered with Apple by the author.
- *
- * The JPEG Convert program is an image format conversion program that utilizes the software of
- * the Independent JPEG Group. The JPEG Convert program is essentially a Macintosh user interface
- * around the Independent JPEG Group's code. The author of JPEG Convert maintains a copyright to
- * the interface software only. For conditions of distribution and use of the Independent JPEG
- * Group's software, refer to the README file contained in the Independent JPEG Group's distribution
- * package.
- *
- * (Further use of the word 'software' refers only to the source files for implementing this user
- * interface, including the resource file which does not include this comment. It does NOT refer
- * to the Independent JPEG Group's code.)
- *
- * The conditions for distribution of this software are as follows:
- * This software may be freely distributed provided that it is not distributed for profit; a
- * nominal copying fee may be charged.
- *
- * Any distribution of this software must contain all original copyright notices.
- *
- * The conditions for use of this software IN FULL are as follows:
- * This software may be used in full by any person or business provided that the person or
- * business is not seeking profits directly from the use of this software.
- *
- * The conditions for use of this software IN PART are as follows:
- * Any person or business may copy and utilize portions of this software in other products
- * provided that a note that "portions of the software are copyright by James H. Brunner"
- * is included in the software AND the resultant software is not intended to be distributed
- * for profit.
- *
- * If SOURCE for projects containing portions of this code is not to be made available
- * with the resultant programs, an additional note that "portions of the software are
- * copyright James H. Brunner" must be included in some visable user documentation.
- *
- * Bottom line: I give it away free; I don't want you selling it. You can use the source if
- * you wish, but don't sell it. If you use my work, give me credit for it.
- */
-
- /*
- * JPEG Convert1.c
- *
- * This is part 1 of the Macintosh GUI (Graphical User Interface). It is intended to be
- * compiled on a Macintosh computer with Think C. This contains almost all the "meat".
- * "JPEG Convert2.c" contains the source for the dialog boxes. This contains the rest.
- */
-
-
- #define MAC_COPYRIGHT "Macintosh interface: Copyright (C) 1993, James H. Brunner"
-
-
- #include "JPEG Convert.h"
-
- /* MAC INCLUDES */
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Fonts.h>
- #include <Desk.h>
- #include <OSUtils.h>
- #include <Traps.h>
- #include <GestaltEqu.h>
- #include <Script.h>
- #include <BDC.h>
- #include <LoMem.h>
- #include <OSEvents.h>
-
- /* UNIX INCLUDES */
- #include <errno.h>
- #include <setjmp.h>
-
- /* INDEPENDENT JPEG GROUP INCLUDES */
- #include "jversion.h"
-
- #define _DialogDispatch 0xAA68
-
- #define PROGRESS_DLOG 152
- #define REPLACE_DLOG 200
-
- #define ERROR_ALERT_ID 666
-
- #define MENUCOUNT 3
- #define APPLE_ID 128
- #define FILE_ID 129
- #define EDIT_ID 130
-
- #define APPLE_M 0
- #define FILE_M 1
- #define EDIT_M 2
-
- #define APPLE_ABOUT 1
-
- #define FILE_OPEN 1
- #define FILE_ABORT 3
- #define FILE_PREFS 4
- #define FILE_QUIT 6
-
- #define EDIT_UNDO 1
- #define EDIT_CUT 3
- #define EDIT_COPY 4
- #define EDIT_PASTE 5
- #define EDIT_CLEAR 6
-
- #define PROG_ABORT 1
- #define PROG_SCROLL 2
-
- #define LONGJMP_ABORT 1
- #define LONGJMP_ERROR 2
-
- #define VIS_MSG_LINES 9
- #define MEMORY_FUDGE 100000
- #define MAX_FILE_TYPES 20
-
-
- /* Use the preprocessor for a bit of error checking. */
-
- #if DEFAULT_FMT == FMT_GIF
- #ifndef GIF_SUPPORTED
- #error The default format is unsupported!
- #endif
- #elif DEFAULT_FMT == FMT_PPM
- #ifndef PPM_SUPPORTED
- #error The default format is unsupported!
- #endif
- #elif DEFAULT_FMT == FMT_RLE
- #ifndef RLE_SUPPORTED
- #error The default format is unsupported!
- #endif
- #elif DEFAULT_FMT == FMT_TARGA
- #ifndef TARGA_SUPPORTED
- #error The default format is unsupported!
- #endif
- #elif DEFAULT_FMT == FMT_JPEG
- #error The default format can not be JPEG
- #endif
-
- #ifdef GIF_SUPPORTED
- #ifndef QUANT_1PASS_SUPPORTED
- #ifndef QUANT_2PASS_SUPPORTED
- #error Must support quantizing for GIF
- #endif
- #endif
- #endif
-
- /* GLOBAL VARS */
- static Boolean gDone=FALSE; /* TRUE when the program is quitting */
- static Boolean gAbort=FALSE; /* TRUE when the user has selected abort all */
- static Boolean gInBackground=FALSE; /* TRUE when application is in background */
- static Boolean gProcessing=FALSE; /* TRUE while JPEG code is processing */
- static Boolean gDropStart=TRUE; /* TRUE if application was launched by dropping file */
- static Boolean gDirChanged=FALSE; /* TRUE after we have changed the stdfile directory */
-
- GLOBAL Boolean gNewDialogMgr; /* TRUE if the system 7 dialog manager is available */
- GLOBAL Boolean gAppleEvents; /* TRUE if system 7 apple events are available */
- GLOBAL Boolean gColorQuickdraw; /* TRUE if color qd and main screen > 4 colors */
- GLOBAL Boolean gFSSpecSupport; /* TRUE if machine supports FSSpecs */
- static Boolean gWaitNextEvent; /* TRUE if WaitNextEvent is available */
- static Boolean gStandardFile58; /* TRUE if the system 7 standard file calls are available */
-
- static MenuHandle gMenu[MENUCOUNT]; /* a list of the menu handles */
- static Rect gDragRect; /* the drag rect for the progress monitor */
-
- static OSType gTypeList[MAX_FILE_TYPES]; /* Type list for open file */
- static short gTypeListCount; /* number of items in gTypeList */
-
- GLOBAL PrefHandle gPrefs; /* User prefs from preference file and/or dialog */
-
- static long gMemory95; /* Available memory in bytes less 5%. This is measured once */
- /* at program startup because after the JPEG code uses */
- /* malloc and free, who knows if those routines actually */
- /* free the memory back to the Mac OS. */
-
- static struct External_methods_struct e_methods; /* for the IJG code */
-
- static ImageFormat requested_fmt; /* requested output format (DJPEG) */
- static jmp_buf longjmp_data; /* a long-jump buffer for error aborts */
- static boolean is_targa; /* records user -T switch */
-
- static long last_message_time; /* time last message written to progress wind (ticks) */
- static TEHandle errText; /* handle to text in progress window */
- static short curErrLine; /* line number of top line of text in progress wind */
-
- static DialogPtr progressMonitorWindow;
- static Rect progressTextView={95, 22, 194, 403};
- static Rect progressBarRect={35, 20, 55, 420};
- static long progressPercent400; /* completion percent on a scale of 0-400 */
- static Str63 progressFileName; /* file name displayed in progress window */
-
-
- static char format_buffer[132];
- #define FORMAT1(text, data1) (sprintf(format_buffer, (text), (data1)) ? (char *)&format_buffer : (char *)&format_buffer)
-
-
- LOCAL void
- ProcessOutstandingEvents (void);
-
-
- /* Stolen from TCL */
- LOCAL Boolean
- TrapAvailable (short theTrap)
- {
- TrapType tType;
- short numToolBoxTraps;
-
- tType = (theTrap & 0x800) > 0 ? ToolTrap : OSTrap;
-
- if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- numToolBoxTraps = 0x200;
- else
- numToolBoxTraps = 0x400;
-
- if (tType == ToolTrap) {
- theTrap &= 0x7FF;
- if (theTrap >= numToolBoxTraps)
- theTrap = _Unimplemented;
- }
-
- return (NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap));
- }
-
-
- /* (from JDMAIN)
- * This routine gets control after the input file header has been read.
- * It must determine what output file format is to be written,
- * and make any other decompression parameter changes that are desirable.
- */
- METHODDEF void
- d_ui_method_selection (decompress_info_ptr cinfo)
- {
- /* if grayscale or CMYK input, force similar output; */
- /* else leave the output colorspace as set by options. */
- if (cinfo->jpeg_color_space == CS_GRAYSCALE)
- cinfo->out_color_space = CS_GRAYSCALE;
- else if (cinfo->jpeg_color_space == CS_CMYK)
- cinfo->out_color_space = CS_CMYK;
-
- /* select output file format */
- /* Note: jselwxxx routine may make additional parameter changes,
- * such as forcing color quantization if it's a colormapped format.
- */
- switch (requested_fmt) {
- #ifdef GIF_SUPPORTED
- case FMT_GIF:
- jselwgif(cinfo);
- break;
- #endif
- #ifdef PPM_SUPPORTED
- case FMT_PPM:
- jselwppm(cinfo);
- break;
- #endif
- #ifdef RLE_SUPPORTED
- case FMT_RLE:
- jselwrle(cinfo);
- break;
- #endif
- #ifdef TARGA_SUPPORTED
- case FMT_TARGA:
- jselwtarga(cinfo);
- break;
- #endif
- default:
- ERREXIT(cinfo->emethods, "Unsupported output file format");
- break;
- }
- }
-
-
- /* (from JCMAIN)
- * select the input file type based on the first character of the input file and the TARGA flag
- */
- LOCAL void
- select_file_type (compress_info_ptr cinfo)
- {
- int c;
-
- if (is_targa) {
- #ifdef TARGA_SUPPORTED
- jselrtarga(cinfo);
- #else
- ERREXIT(cinfo->emethods, "Targa support was not compiled");
- #endif
- return;
- }
-
- if ((c = getc(cinfo->input_file)) == EOF)
- ERREXIT(cinfo->emethods, "Empty input file");
-
- switch (c) {
- #ifdef GIF_SUPPORTED
- case 'G':
- jselrgif(cinfo);
- break;
- #endif
- #ifdef PPM_SUPPORTED
- case 'P':
- jselrppm(cinfo);
- break;
- #endif
- #ifdef RLE_SUPPORTED
- case 'R':
- jselrrle(cinfo);
- break;
- #endif
- #ifdef TARGA_SUPPORTED
- case 0x00:
- jselrtarga(cinfo);
- break;
- #endif
- default:
- #ifdef TARGA_SUPPORTED
- ERREXIT(cinfo->emethods, "Unrecognized input file format --- did you forget -T ?");
- #else
- ERREXIT(cinfo->emethods, "Unrecognized input file format");
- #endif
- break;
- }
-
- if (ungetc(c, cinfo->input_file) == EOF)
- ERREXIT(cinfo->emethods, "ungetc failed");
- }
-
-
- /* (from JCMAIN)
- * This routine gets control after the input file header has been read.
- * It must determine what output JPEG file format is to be written,
- * and make any other compression parameter changes that are desirable.
- */
-
- METHODDEF void
- c_ui_method_selection (compress_info_ptr cinfo)
- {
- /* If the input is gray scale, generate a monochrome JPEG file. */
- if (cinfo->in_color_space == CS_GRAYSCALE)
- j_monochrome_default(cinfo);
- /* For now, always select JFIF output format. */
- #ifdef JFIF_SUPPORTED
- jselwjfif(cinfo);
- #else
- #error You must have JFIF_SUPPORTED
- #endif
- }
-
-
- /*
- * Display an error dialog
- */
- GLOBAL void
- Error (OSErr eCode, unsigned char *p1, unsigned char *p2)
- {
- Str63 p0;
- long p0l;
-
- if (gAppleEvents)
- if (AEInteractWithUser(kAEDefaultTimeout, NULL, NULL)) {
- SysBeep(0L);
- return;
- }
-
- p0l = eCode;
- NumToString(p0l, p0);
- ParamText(p0, p1, p2, NULL);
- Alert(ERROR_ALERT_ID, NULL);
- }
-
-
- /* This is the Mac trace_message routine. It adds a line of text to the textEdit item and
- * updates the dialog (which better be active). This routine also processes all of the events
- * that may have occurred since this interface was last in control.
- */
- METHODDEF void
- trace_message (const char *msgtext)
- {
- char msgbuffer[256];
- long msglen;
- ControlHandle scrollHand;
- int original_lines;
- int additional_lines;
-
- ProcessOutstandingEvents();
-
- msglen = sprintf(msgbuffer, msgtext,
- e_methods.message_parm[0], e_methods.message_parm[1],
- e_methods.message_parm[2], e_methods.message_parm[3],
- e_methods.message_parm[4], e_methods.message_parm[5],
- e_methods.message_parm[6], e_methods.message_parm[7]);
-
- msgbuffer[msglen++] = '\r';
-
- original_lines = (**errText).nLines;
- TEInsert(msgbuffer, msglen, errText);
- additional_lines = (**errText).nLines - original_lines;
-
- scrollHand = CITEMH(progressMonitorWindow, PROG_SCROLL);
- if ((**errText).nLines > VIS_MSG_LINES) {
- if (GetCtlValue(scrollHand) == GetCtlMax(scrollHand)) {
- SetCtlMax(scrollHand, (**errText).nLines - VIS_MSG_LINES);
- SetCtlValue(scrollHand, (**errText).nLines - VIS_MSG_LINES);
- TEScroll(0, -additional_lines * (**errText).lineHeight, errText);
- curErrLine += additional_lines;
- } else {
- SetCtlMax(scrollHand, (**errText).nLines - VIS_MSG_LINES);
- }
- } else {
- TEUpdate(&progressTextView, errText);
- }
-
- last_message_time = TickCount();
-
- ProcessOutstandingEvents();
- }
-
-
- /* This is the Mac error_exit routine. It generates an error dialog, frees all allocated memory,
- * and longjmp's back to the dialog routine (we don't want to "exit(0)").
- */
- METHODDEF void
- error_exit (const char *msgtext)
- {
- long ticks;
- char msgbuffer[256];
-
- e_methods.free_all(); /* clean up memory allocation */
-
- sprintf(msgbuffer, msgtext,
- e_methods.message_parm[0], e_methods.message_parm[1],
- e_methods.message_parm[2], e_methods.message_parm[3],
- e_methods.message_parm[4], e_methods.message_parm[5],
- e_methods.message_parm[6], e_methods.message_parm[7]);
- CtoPstr(msgbuffer);
- Error(0, "\pUnrecoverable error:", (PSTR)msgbuffer);
-
- longjmp(longjmp_data, LONGJMP_ERROR);
- }
-
-
- /* This routine sets up our error and trace message routines
- */
- LOCAL void
- macselerror ()
- {
- e_methods.error_exit = error_exit;
- e_methods.trace_message = trace_message;
-
- e_methods.trace_level = 0; /* default = no tracing */
-
- e_methods.num_warnings = 0; /* no warnings emitted yet */
- /* By default, the first corrupt-data warning will be displayed,
- * but additional ones will appear only if trace level is at least 2.
- * A corrupt data file could generate many warnings, so it's a good idea
- * to suppress additional messages at default tracing level.
- */
- e_methods.first_warning_level = 0;
- e_methods.more_warning_level = 2;
- }
-
-
- /*
- * Optional routine to display a percent-done figure on stderr.
- * See jcdeflts.c for explanation of the information used.
- */
- LOCAL void
- draw_progress_monitor (completeUpdate)
- Boolean completeUpdate;
- {
- Rect r;
-
- if (completeUpdate) {
- TextFont(0); // For some reason, if I don't do this, under system 6,
- TextFace(0); // the static text in the dialog draws fine the first time
- TextMode(1); // and then, after the TE item is drawn, the window's font
- TextSize(0); // changes to match that of the text item. Go figure.
-
- ParamText(progressFileName, NULL, NULL, NULL);
- DrawDialog(progressMonitorWindow);
-
- r = progressBarRect;
- InsetRect(&r, -2, -2);
- PenSize(2, 2);
- FrameRect(&r);
-
- r = progressTextView;
- InsetRect(&r, -4, -2);
- PenSize(1, 1);
- FrameRect(&r);
-
- TEUpdate(&progressTextView, errText);
- }
-
- r = progressBarRect;
- r.right = 20 + progressPercent400;
-
- ForeColor(blueColor);
- FillRect(&r, gray);
- ForeColor(blackColor);
- }
-
-
- /* Action proc for the scroll bar in the progress monitor. This routine takes case of
- * scrolling the text up or down (lines or pages) while the mouse is held down in the
- * scroll bar.
- */
- METHODDEF pascal void
- scroll_action_proc (ControlHandle theControl, short partCode)
- {
- short currentValue;
- short boundingValue;
- short delta;
-
- currentValue = GetCtlValue(theControl);
- switch (partCode) {
- case inUpButton:
- boundingValue = GetCtlMin(theControl);
- if (currentValue > boundingValue) {
- SetCtlValue(theControl, currentValue-1);
- TEScroll(0, (**errText).lineHeight, errText);
- curErrLine--;
- }
- break;
- case inDownButton:
- boundingValue = GetCtlMax(theControl);
- if (currentValue < boundingValue) {
- SetCtlValue(theControl, currentValue+1);
- TEScroll(0, -(**errText).lineHeight, errText);
- curErrLine++;
- }
- break;
- case inPageUp:
- boundingValue = GetCtlMin(theControl);
- if (currentValue > boundingValue) {
- delta = MIN(currentValue-boundingValue, VIS_MSG_LINES-1);
- SetCtlValue(theControl, currentValue-delta);
- TEScroll(0, delta * (**errText).lineHeight, errText);
- curErrLine -= delta;
- }
- break;
- case inPageDown:
- boundingValue = GetCtlMax(theControl);
- if (currentValue < boundingValue) {
- delta = MIN(boundingValue-currentValue, VIS_MSG_LINES-1);
- SetCtlValue(theControl, currentValue+delta);
- TEScroll(0, -delta * (**errText).lineHeight, errText);
- curErrLine += delta;
- }
- break;
- }
- }
-
-
- /* This routine displays the progress monitor dialog window. It allocates the textEdit record
- * used for trace messages. It initializes the bar graph to zero and sets the gProcessing flag.
- *
- * This interface assumes that if gProcessing is true, that it is OK to longjmp on an error. Make
- * sure that setjmp is called right after this routine (before any events are handled).
- */
- LOCAL void
- open_progress_monitor (fileName)
- Str63 fileName;
- {
- int i;
- static Boolean checked_window_loc=FALSE;
-
- for (i=0; i <= fileName[0]; i++)
- progressFileName[i] = fileName[i];
-
- progressMonitorWindow = GetNewDialog(PROGRESS_DLOG, NULL, (WindowPtr)-1);
-
- MoveWindow(progressMonitorWindow, (**gPrefs).progressLoc.h, (**gPrefs).progressLoc.v, FALSE);
- ShowWindow(progressMonitorWindow);
-
- /* make sure the user can grab the title bar. He may have changed monitor config, etc */
- if (!checked_window_loc) {
- Rect titleBarRect;
-
- checked_window_loc = TRUE;
-
- titleBarRect = (**((*(WindowPeek)progressMonitorWindow).strucRgn)).rgnBBox;
- titleBarRect.bottom = (**((*(WindowPeek)progressMonitorWindow).contRgn)).rgnBBox.top;
-
- if (!SectRect(&titleBarRect, &gDragRect, &titleBarRect)) {
- (**gPrefs).progressLoc.h = 20;
- (**gPrefs).progressLoc.v = 40;
- ChangedResource((Handle)gPrefs);
- MoveWindow(progressMonitorWindow, (**gPrefs).progressLoc.h, (**gPrefs).progressLoc.v, FALSE);
- }
- }
-
- SetPort(progressMonitorWindow);
- errText = TENew(&progressTextView, &progressTextView);
- (**errText).txFont = monaco;
- (**errText).txFace = 0;
- (**errText).txSize = 9;
- (**errText).lineHeight = 11;
- (**errText).fontAscent = 9;
-
- curErrLine = 0;
-
- gProcessing = TRUE;
- progressPercent400 = 0;
-
- draw_progress_monitor(TRUE);
- }
-
-
- /* This routine removed the progress monitor from the screen and deallocates the testEdit
- * record used for trace messages. This routine also checks the time when the last message
- * was written to the window and will pause to make sure that the user has had time to
- * read the message before removing the window.
- */
- LOCAL void
- close_progress_monitor ()
- {
- long ticks_since_last_msg;
-
- ticks_since_last_msg = TickCount() - last_message_time;
- if (ticks_since_last_msg < 60)
- Delay(60 - ticks_since_last_msg, &ticks_since_last_msg);
-
- DisposDialog(progressMonitorWindow);
-
- TEDispose(errText);
-
- gProcessing = FALSE;
- }
-
-
- /* Process events and update the bar graph according to progress.
- */
- LOCAL void
- progress_monitor (completed_passes, total_passes, loopcounter, looplimit)
- int completed_passes, total_passes;
- long loopcounter, looplimit;
- {
- ProcessOutstandingEvents();
-
- progressPercent400 = 400 * completed_passes / total_passes;
- progressPercent400 += ((400 * loopcounter) / total_passes) / looplimit;
-
- draw_progress_monitor(FALSE);
- }
-
-
- /* These two routines are the progress monitor interfaces for DJPEG and CJPEG.
- * They simply call the common progress_monitor routine.
- */
- METHODDEF void
- c_progress_monitor (compress_info_ptr cinfo, long loopcounter, long looplimit)
- {
- progress_monitor(cinfo->completed_passes, cinfo->total_passes, loopcounter, looplimit);
- }
- METHODDEF void
- d_progress_monitor (decompress_info_ptr cinfo, long loopcounter, long looplimit)
- {
- progress_monitor(cinfo->completed_passes, cinfo->total_passes, loopcounter, looplimit);
- }
-
-
- /* Given a file spec, return a path name */
- GLOBAL OSErr
- FSSpecToName (FSSpec spec, Str255 fullname)
- {
- Str63 dirName; /* allow room for a 31 char file/dir name + a ':' */
- CInfoPBRec di;
- OSErr err;
-
- fullname[0] = 0;
-
- dirName[0] = 0;
- di.dirInfo.ioNamePtr = dirName;
- di.dirInfo.ioDrParID = spec.parID;
-
- BlockMove(spec.name, fullname, spec.name[0]+1);
-
- do {
- di.dirInfo.ioVRefNum = spec.vRefNum;
- di.dirInfo.ioFDirIndex = -1;
- di.dirInfo.ioDrDirID = di.dirInfo.ioDrParID;
-
- err = PBGetCatInfo(&di, FALSE);
- if (err == noErr) {
- dirName[++dirName[0]] = ':';
- if ((int)dirName[0] + (int)fullname[0] > 255)
- return bdNamErr;
- else
- CONCAT(fullname, dirName, fullname);
- } else
- return err;
- } while (di.dirInfo.ioDrDirID != fsRtDirID);
-
- return noErr;
- }
-
-
- /* CenterRect: Center a rectangle on the main screen */
- LOCAL void
- CenterRect (Rect *r)
- {
- short delta;
- short screenTop;
-
- delta = r->right - r->left;
- r->left = (screenBits.bounds.right - delta) >> 1;
- r->right = r->left + delta;
-
- /* Determine top of screen */
- screenTop = GetMBarHeight();
-
- /* Place it in upper third of screen */
- delta = r->bottom - r->top;
- r->top = (screenBits.bounds.bottom - screenTop - delta) / 3 + screenTop;
- r->bottom = r->top + delta;
- }
-
-
- /* CenterDialog: Center a dialog on the main screen before creating it */
- GLOBAL void
- CenterDialog (short id, Point *corner)
- {
- DialogTHndl theDLOG;
- Rect bounds;
-
- /* Get the DLOG resource */
- theDLOG = (DialogTHndl)GetResource('DLOG', id);
- if (!theDLOG)
- return;
-
- /* Center it within screenBits */
- bounds = (*theDLOG)->boundsRect;
- CenterRect(&bounds);
- (*theDLOG)->boundsRect = bounds;
-
- if (corner)
- *corner = topLeft(bounds);
- }
-
-
- /*
- * This routine will set the file type and creator for the given file to whatever is appropriate
- * for the given ImageFormat.
- */
- LOCAL void
- set_file_type (FSSpec file, ImageFormat format)
- {
- FInfo finfo;
- OSErr err;
- Str255 tempName;
-
- FSSpecToName(file, tempName);
- err = GetFInfo(tempName, file.vRefNum, &finfo);
- if (err == noErr) {
- switch (format) {
- case FMT_GIF:
- finfo.fdType = (**gPrefs).gif_type;
- finfo.fdCreator = (**gPrefs).gif_creator;
- break;
- case FMT_PPM:
- finfo.fdType = (**gPrefs).ppm_type;
- finfo.fdCreator = (**gPrefs).ppm_creator;
- break;
- case FMT_RLE:
- finfo.fdType = (**gPrefs).rle_type;
- finfo.fdCreator = (**gPrefs).rle_creator;
- break;
- case FMT_TARGA:
- finfo.fdType = (**gPrefs).targa_type;
- finfo.fdCreator = (**gPrefs).targa_creator;
- break;
- case FMT_JPEG:
- finfo.fdType = (**gPrefs).jpeg_type;
- finfo.fdCreator = (**gPrefs).jpeg_creator;
- break;
- default:
- finfo.fdType = '????'; /* wasn't expecting this... */
- finfo.fdCreator = appSignature;
- }
- SetFInfo(tempName, file.vRefNum, &finfo);
- }
- }
-
-
- /*
- * This routine checks for the existance of a file. If it exists, the user is prompted to
- * see if it is ok to replace the file. If the user says OK or if the file does not exist,
- * true is returned.
- */
- LOCAL Boolean
- ok_to_replace (FSSpec file)
- {
- DialogPtr d;
- Boolean replace_ok=FALSE;
- short item;
- OSErr err;
- FSSpec tempSpec;
-
- /* If user pref is to overwrite, just return TRUE */
- if ((**gPrefs).overwrite)
- return TRUE;
-
- /* does the file exist? */
- err = xFSMakeFSSpec(file.vRefNum, file.parID, file.name, &tempSpec);
- replace_ok = (err == fnfErr);
-
- /* if it exists, ask if OK to replace. */
- if (!replace_ok) {
- if (gAppleEvents)
- if (AEInteractWithUser(kAEDefaultTimeout, NULL, NULL)) {
- SysBeep(0L);
- return FALSE;
- }
-
- if (!gNewDialogMgr)
- CenterDialog(REPLACE_DLOG, NULL);
-
- d = GetNewDialog(REPLACE_DLOG, NULL, (WindowPtr)-1);
- ParamText(file.name, NULL, NULL, NULL);
-
- /* If using the new dialog manager, border the cancel button and set as a default */
- /* If using system 6, will just use plain old buttons. Easier. */
- if (gNewDialogMgr) {
- SetDialogDefaultItem(d, cancel);
- SetDialogCancelItem(d, cancel);
- }
-
- ShowWindow(d);
- ModalDialog(NULL, &item);
- replace_ok = (item == ok);
- DisposDialog(d);
- }
-
- return replace_ok;
- }
-
-
- /*
- * This is the routine that does all of the work when a jpeg file is dropped. It calls the
- * routine to diaplay the dialog (if necessary), and calls the jpeg routine to do the
- * processing work.
- */
- LOCAL void
- process_a_jpeg_file (FSSpec inputFile, char *fullinfile)
- {
- static Boolean do_all=FALSE;
- static djpeg_dlog_data dlog_info;
- Str255 fulloutfile;
- short item;
- int longjmp_reason;
- long curTicks;
-
- /* Have we been here before and did the user hit the OK ALL button? If not, we dialog. */
- if (!do_all) {
- switch (item = display_djpeg_dialog(inputFile, &dlog_info)) {
- case J_OK_ALL:
- do_all = TRUE;
- case J_OK:
- break;
- }
- } else {
- /* They hit OK_ALL on a previous file. Just create a unique name. */
- fix_name(dlog_info.outfile.name, inputFile.name, requested_fmt);
- dlog_info.replace_ok = FALSE;
- }
-
- FSSpecToName(dlog_info.outfile, fulloutfile);
- PtoCstr(fulloutfile);
-
- /* We're gonna do it. Set up the structures, open the files, and do it to it... */
- if (do_all || item == J_OK) {
- struct Decompress_info_struct cinfo;
- struct Decompress_methods_struct dc_methods;
-
- /* Check if it's ok write the output file */
- if (!dlog_info.replace_ok)
- if (!ok_to_replace(dlog_info.outfile))
- return;
-
- /* Initialize the system-dependent method pointers. */
- cinfo.methods = &dc_methods;
- cinfo.emethods = &e_methods;
- macselerror(); /* error/trace message routines */
- jselmemmgr(&e_methods); /* memory allocation routines */
- dc_methods.d_ui_method_selection = d_ui_method_selection;
-
- /* Set up default JPEG parameters. */
- j_d_defaults(&cinfo, TRUE);
-
- /* Scan command line options, adjust parameters */
- if (dlog_info.smoothing)
- cinfo.do_block_smoothing = TRUE;
-
- if (dlog_info.grayscale)
- cinfo.out_color_space = CS_GRAYSCALE;
-
- if (dlog_info.quantize) {
- cinfo.quantize_colors = TRUE;
- cinfo.desired_number_of_colors = dlog_info.colors;
- }
-
- if (dlog_info.onepass)
- cinfo.two_pass_quantize = FALSE;
-
- if (dlog_info.nodither)
- cinfo.use_dithering = FALSE;
-
- e_methods.trace_level = dlog_info.debug;
- e_methods.max_memory_to_use = gMemory95;
-
- /* Start up progress display */
- dc_methods.progress_monitor = d_progress_monitor;
-
- /* Do it to it! */
- open_progress_monitor(inputFile.name);
- if (longjmp_reason = setjmp(longjmp_data)) { /* An error or an abort */
- switch (longjmp_reason) {
- case LONGJMP_ABORT:
- WARNMS(&e_methods, "processing aborted.");
- e_methods.free_all(); /* clean up memory allocation */
- break;
- case LONGJMP_ERROR:
- break;
- }
- fclose(stdin);
- fclose(stdout);
- CtoPstr((CSTR)fulloutfile);
- FSDelete(fulloutfile, dlog_info.outfile.vRefNum);
- close_progress_monitor();
- return;
- }
-
- /* print version identification */
- TRACEMS(&e_methods, 0, FORMAT1("Independent JPEG Group's DJPEG, version %s", JVERSION));
- TRACEMS(&e_methods, 1, JCOPYRIGHT);
- TRACEMS(&e_methods, 1, MAC_COPYRIGHT);
-
- /* Select the input and output files */
- PtoCstr(inputFile.name);
- TRACEMS(&e_methods, 1, FORMAT1("converting %s from jpeg format.", inputFile.name));
- CtoPstr((CSTR)inputFile.name);
-
- TRACEMS(&e_methods, 2, FORMAT1("input file path: %s", fullinfile));
- freopen((CSTR)fullinfile, "rb", stdin);
- if ((cinfo.input_file = stdin) == NULL)
- ERREXIT(&e_methods, FORMAT1("can't open %s", fullinfile));
-
- TRACEMS(&e_methods, 2, FORMAT1("output file path: %s", fulloutfile));
- freopen((CSTR)fulloutfile, "wb", stdout);
- if ((cinfo.output_file = stdout) == NULL)
- ERREXIT(&e_methods, FORMAT1("can't open %s", fulloutfile));
-
- /* Set up to read a JFIF or baseline-JPEG file. */
- /* A smarter UI would inspect the first few bytes of the input file */
- /* to determine its type. */
- #ifdef JFIF_SUPPORTED
- jselrjfif(&cinfo);
- #else
- #error You must have JFIF_SUPPORTED
- #endif
-
- requested_fmt = dlog_info.format;
- set_file_type(dlog_info.outfile, requested_fmt);
- jpeg_decompress(&cinfo);
- progress_monitor(1,1,0,1);
- Delay(30, &curTicks);
-
- close_progress_monitor();
- }
- }
-
-
- /*
- * This is the routine that does all of the work when a non-jpeg file is dropped. It calls
- * a routine to display the dialog (if necessary), and calls the jpeg routine to do the
- * processing work.
- */
- LOCAL void
- process_a_nonjpeg_file (FSSpec inputFile, char *fullinfile)
- {
- static Boolean do_all=FALSE;
- static cjpeg_dlog_data dlog_info;
- Str255 fulloutfile;
- short item;
- int longjmp_reason;
- long curTicks;
-
- /* Have we been here before and did the user hit the OK ALL button? If not, we dialog. */
- if (!do_all) {
- switch (item = display_cjpeg_dialog(inputFile, &dlog_info)) {
- case J_OK_ALL:
- do_all = TRUE;
- case J_OK:
- break;
- }
- } else {
- /* If do all was selected on a previous dialog, just generate the output file name */
- fix_name(dlog_info.outfile.name, inputFile.name, FMT_JPEG);
- dlog_info.replace_ok = FALSE;
- }
-
- FSSpecToName(dlog_info.outfile, fulloutfile);
- PtoCstr(fulloutfile);
-
- /* And now, set up the data structures, open the files, and do it to it. */
- if (do_all || item == J_OK) {
- struct Compress_info_struct cinfo;
- struct Compress_methods_struct c_methods;
-
- /* Check if it's ok write the output file */
- if (!dlog_info.replace_ok)
- if (!ok_to_replace(dlog_info.outfile))
- return;
-
- /* Initialize the system-dependent method pointers. */
- cinfo.methods = &c_methods;
- cinfo.emethods = &e_methods;
- macselerror(); /* error/trace message routines */
- jselmemmgr(&e_methods); /* memory allocation routines */
- c_methods.c_ui_method_selection = c_ui_method_selection;
-
- /* Set up default JPEG parameters. */
- j_c_defaults(&cinfo, 75, FALSE); /* default quality level = 75 */
-
- /* Scan command line options, adjust parameters */
- if (dlog_info.grayscale)
- j_monochrome_default(&cinfo);
-
- /* Note: for now, we make force_baseline FALSE.
- * This means non-baseline JPEG files can be created with low Q values.
- * To ensure only baseline files are generated, pass TRUE instead.
- */
- j_set_quality(&cinfo, dlog_info.quality, FALSE);
-
- is_targa = dlog_info.targa;
-
- if (dlog_info.optimize)
- cinfo.optimize_coding = TRUE;
-
- #ifdef ARITH_CODING_SUPPORTED
- if (dlog_info.arithmetic)
- cinfo.arith_code = TRUE;
- #endif
- #ifdef MULTISCAN_FILES_SUPPORTED
- if (dlog_info.nointerleave)
- cinfo.interleave = FALSE;
- #endif
-
- e_methods.trace_level = dlog_info.debug;
- e_methods.max_memory_to_use = gMemory95;
-
- /* Start up progress display */
- c_methods.progress_monitor = c_progress_monitor;
-
- /* Do it to it! */
- open_progress_monitor(inputFile.name);
- if (longjmp_reason = setjmp(longjmp_data)) { /* An error or an abort */
- switch (longjmp_reason) {
- case LONGJMP_ABORT:
- WARNMS(&e_methods, "processing aborted.");
- e_methods.free_all(); /* clean up memory allocation */
- break;
- case LONGJMP_ERROR:
- break;
- }
- fclose(stdin);
- fclose(stdout);
- CtoPstr((CSTR)fulloutfile);
- FSDelete(fulloutfile, dlog_info.outfile.vRefNum);
- close_progress_monitor();
- return;
- }
-
- /* print version identification */
- TRACEMS(&e_methods, 0, FORMAT1("Independent JPEG Group's CJPEG, version %s", JVERSION));
- TRACEMS(&e_methods, 1, JCOPYRIGHT);
- TRACEMS(&e_methods, 1, MAC_COPYRIGHT);
-
- /* Select the input and output files */
- PtoCstr(inputFile.name);
- TRACEMS(&e_methods, 1, FORMAT1("converting %s to jpeg format.", inputFile.name));
- CtoPstr((CSTR)inputFile.name);
-
- TRACEMS(&e_methods, 2, FORMAT1("input file path: %s", fullinfile));
- freopen((CSTR)fullinfile, "rb", stdin);
- if ((cinfo.input_file = stdin) == NULL)
- ERREXIT(&e_methods, FORMAT1("can't open %s", fullinfile));
-
- TRACEMS(&e_methods, 2, FORMAT1("output file path: %s", fulloutfile));
- freopen((CSTR)fulloutfile, "wb", stdout);
- if ((cinfo.output_file = stdout) == NULL)
- ERREXIT(&e_methods, FORMAT1("can't open %s", fulloutfile));
-
- /* Figure out the input file format, and set up to read it. */
- select_file_type(&cinfo);
-
- set_file_type(dlog_info.outfile, FMT_JPEG);
- jpeg_compress(&cinfo);
- progress_monitor(1,1,0,1);
- Delay(30, &curTicks);
-
- close_progress_monitor();
- }
- }
-
- /*
- * This routine gets called once for each dropped file. It converts the FSSpec to a full
- * path name, checks to see if the file is jpeg or not, and calls the appropriate routine
- * to dialog (if necessary) and convert.
- */
- LOCAL void
- process_a_dropped_file (FSSpec spec)
- {
- OSErr rc;
- Boolean jpeg=FALSE;
- int char1;
- Str255 fullname;
-
- /* convert the FSSpec to a full pathname (for the stdio routines) */
- if ((rc = FSSpecToName(spec, fullname)) != noErr) {
- Error(rc, "\pCan't convert file spec to pathname", fullname);
- return;
- }
-
- /* open file */
- PtoCstr(fullname);
- freopen((CSTR)fullname, "rb", stdin);
- if (stdin == NULL) {
- CtoPstr((CSTR)fullname);
- Error(0, "\pError opening input file", fullname);
- return;
- }
-
- /* check if jpeg */
- char1 = getchar();
- if (char1 == -1) {
- Error(0, "\pUnexpected EOF", "\pCan't read input file");
- fclose(stdin);
- return;
- }
- if (char1 == 0xff)
- if (getchar() == 0xd8)
- jpeg = TRUE;
-
- /* close file */
- fclose(stdin);
-
- /* display dialog & convert */
- if (jpeg)
- process_a_jpeg_file(spec, (CSTR)fullname);
- else
- process_a_nonjpeg_file(spec, (CSTR)fullname);
- }
-
- LOCAL void
- IntroScreen ()
- {
- gDropStart = FALSE; /* the app was started by double-clicking, not dropping */
-
- DoAboutBox();
- }
-
- /*
- * core AppleEvent handlers - only open documents is interesting
- * These event handlers were originally taken from "Flip A BNDL" by Michael S. Engber.
- * (modified as needed)
- */
-
- METHODDEF pascal OSErr
- AEH_oapp (AppleEvent* ae_p, AppleEvent* reply_p, long refCon)
- {
- IntroScreen();
-
- return noErr;
- }
-
-
- METHODDEF pascal OSErr
- AEH_pdoc (AppleEvent* ae_p, AppleEvent* reply_p, long refCon)
- {
- gDone = TRUE;
- return errAEEventNotHandled;
- }
-
-
- METHODDEF pascal OSErr
- AEH_quit (AppleEvent* ae_p, AppleEvent* reply_p, long refCon)
- {
- gDone = TRUE;
- return noErr;
- }
-
-
- METHODDEF pascal OSErr
- AEH_odoc (AppleEvent* ae_p, AppleEvent* reply_p, long refCon)
- {
- long i;
- long docCount;
- short purgeCount;
- Size sz;
- OSErr err;
- DescType type;
- AEDescList docList;
- short wdRefNum;
- FInfo finfo;
-
- if (gDropStart)
- gDone = TRUE;
-
- /* get the list of docs */
- if (err = AEGetParamDesc(ae_p, keyDirectObject, typeAEList, &docList)) {
- Error(err, "\pAEH_odoc", "\pAEGetParamDesc()");
- return err;
- }
-
- /* make sure there are no other parameters */
- switch (err = AEGetAttributePtr(ae_p, keyMissedKeywordAttr, typeWildCard, &type, NULL, 0, &sz)) {
- case errAEDescNotFound:
- err = noErr;
- break;
- case noErr:
- Error(0,"\pAEH_odoc","\pextra AE attributes");
- AEDisposeDesc(&docList);
- return errAEEventNotHandled;
- default:
- Error(err,"\pAEH_odoc","\pAEGetAttributePtr()");
- AEDisposeDesc(&docList);
- return errAEEventNotHandled;
- }
-
- /* loop through & process the docs */
- if (err = AECountItems(&docList, &docCount)) {
- AEDisposeDesc(&docList);
- return err;
- }
-
- for (i=1; i <= docCount && !gAbort; ++i) {
- FSSpec spec;
- AEKeyword key;
-
- if (err = AEGetNthPtr(&docList, i, typeFSS, &key, &type, (Ptr)&spec, sizeof(spec), &sz)) {
- Error(err,"\pAEH_odoc","\pAEGetNthPtr()");
- continue;
- }
-
- if (type != typeFSS) {
- Error(i, "\pAEH_odoc", "\pNth doclist entry failed coercion to FSSpec");
- continue;
- }
-
- /* I absolutely won't allow some files to be processed... */
- err = FSpGetFInfo(&spec, &finfo);
- if (err == noErr) {
- /* treat the prefs file like double clicking on the app */
- if ((finfo.fdType == 'PREF') && (finfo.fdCreator == appSignature)) {
- gDropStart = FALSE;
- gDone = FALSE;
- continue;
- }
- /* I just don't want to mess with applications */
- if (finfo.fdType == 'APPL')
- continue;
- } else {
- Error(err, "\pCan't get file info. Ignoring file:", spec.name);
- continue;
- }
-
- /* Let's be a nice app and set the current directory to where the first file was dropped
- * from. I wish all applications did this. Where else would the user want to save the
- * file? With the application? BAH! BUT, only do it once so as not to confuse the user
- * when the directory keeps changing!
- */
- if (!gDirChanged) {
- gDirChanged = TRUE;
- CurDirStore = spec.parID;
- SFSaveDisk = -spec.vRefNum;
- }
-
- process_a_dropped_file(spec);
- }
-
- AEDisposeDesc(&docList);
- return noErr;
- }
-
-
- /*
- * Initialize the application. Init toolbox routines, etc.
- */
- LOCAL Boolean
- AppInit (void)
- {
- OSErr err;
- int x;
- RgnHandle grayRgn;
- long response;
- long grow_mem;
- short fref_count;
- short fref;
-
- InitGraf(&thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(0L);
-
- FlushEvents(everyEvent, 0);
-
- gTypeListCount = 0;
- for (err = noErr, fref = 1; !err; fref++) {
- OSType **frefHand;
-
- frefHand = (OSType **)GetIndResource('FREF', fref);
- err = ResError();
-
- if (!err)
- if (HomeResFile((Handle)frefHand) != CurResFile())
- err = resNotFound;
-
- if (!err)
- if (**frefHand != 'APPL')
- if (gTypeListCount == MAX_FILE_TYPES) {
- gTypeListCount = -1; /* Too many, allow everything */
- err = resNotFound;
- } else
- gTypeList[gTypeListCount++] = **frefHand;
-
- ReleaseResource((Handle)frefHand);
- }
-
- /* Check for the new traps */
- gNewDialogMgr = TrapAvailable(_DialogDispatch);
- gWaitNextEvent = TrapAvailable(_WaitNextEvent);
-
- /* Use new GetFile if available */
- err = Gestalt(gestaltStandardFileAttr, &response);
- gStandardFile58 = (err == noErr && (response & (1 << gestaltStandardFile58)));
-
- /* Check for Apple Events */
- err = Gestalt(gestaltAppleEventsAttr, &response);
- gAppleEvents = (err == noErr && (response & (1 << gestaltAppleEventsPresent)));
-
- /* Check for color QuickDraw and color monitor */
- err = Gestalt(gestaltQuickdrawVersion, &response);
- gColorQuickdraw = (err == noErr && (response >= gestalt8BitQD));
- if (gColorQuickdraw)
- gColorQuickdraw = ((**(**GetMainDevice()).gdPMap).pixelSize > 2);
-
- /* Check for the support of FSSpecs */
- err = Gestalt(gestaltFSAttr, &response);
- gFSSpecSupport = (err == noErr && (response & (1 << gestaltHasFSSpecCalls)));
-
- /* open the pref file */
- read_preference_file();
-
- gMenu[APPLE_M] = GetMenu(APPLE_ID);
- AddResMenu(gMenu[APPLE_M],'DRVR');
- gMenu[FILE_M] = GetMenu(FILE_ID);
- gMenu[EDIT_M] = GetMenu(EDIT_ID);
- for (x=0; x < MENUCOUNT; x++)
- InsertMenu(gMenu[x],0);
- DrawMenuBar();
-
- InitCursor();
-
- grayRgn = GetGrayRgn();
- gDragRect = (**grayRgn).rgnBBox;
- InsetRect(&gDragRect, 4, 4);
-
- gMemory95 = MaxMem(&grow_mem);
- gMemory95 += grow_mem;
- gMemory95 -= MEMORY_FUDGE;
- gMemory95 = (gMemory95 > 0) ? (gMemory95 * 19L) / 20L : 0; /* free memory - 5% */
-
- /* install core AE handlers */
- if (gAppleEvents) {
- if ((err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, &AEH_oapp, 0L, FALSE)) ||
- (err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments , &AEH_odoc, 0L, FALSE)) ||
- (err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments , &AEH_pdoc, 0L, FALSE)) ||
- (err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, &AEH_quit, 0L, FALSE))) {
- Error(err, "\pAppInit", "\pAEInstallEventHandler");
- return FALSE;
- }
- } else {
- EventRecord theEvent;
-
- // Under system 6, you have to do this before displaying the window
- // or your window will be displayed behind the others until WNE is
- // finally called.
- if (gWaitNextEvent)
- WaitNextEvent(0, &theEvent, 0L, 0L);
- IntroScreen();
- }
-
- return TRUE;
- }
-
-
- /* GetFile: wrapper for StandardGetFile */
- LOCAL void
- GetFile (FileFilterProcPtr fileFilter,
- short numTypes,
- SFTypeList typeList,
- StandardFileReply *reply)
- {
- OSErr err;
- Point where;
- SFReply oldReply;
- long procID;
- FInfo fndrInfo;
-
-
- /* Use new GetFile if available */
- if (gStandardFile58) {
- StandardGetFile(fileFilter, numTypes, typeList, reply);
- return;
- }
-
- /* Must use old GetFile */
- CenterDialog(getDlgID, &where);
- SFGetFile(where, 0, fileFilter, numTypes, typeList, 0, &oldReply);
-
- /* Convert the old reply to a new reply */
- reply->sfGood = oldReply.good;
- if (!reply->sfGood)
- return;
-
- reply->sfType = oldReply.fType;
-
- /* Convert working directory into volume reference and directory ID */
- err = GetWDInfo(oldReply.vRefNum, &reply->sfFile.vRefNum, &reply->sfFile.parID, &procID);
- if (err != noErr) {
- reply->sfFile.vRefNum = oldReply.vRefNum;
- reply->sfFile.parID = 0;
- }
- COPY(reply->sfFile.name, oldReply.fName);
-
- reply->sfScript = smSystemScript;
-
- err = HGetFInfo(reply->sfFile.vRefNum, reply->sfFile.parID, reply->sfFile.name, &fndrInfo);
- reply->sfFlags = (err == noErr) ? fndrInfo.fdFlags : 0;
-
- reply->sfIsFolder = FALSE;
- reply->sfIsVolume = FALSE;
- }
-
-
- /* PutFile: Wrapper for StandardPutFile */
- GLOBAL void
- PutFile (ConstStr255Param prompt,
- ConstStr255Param defaultName,
- StandardFileReply *reply)
- {
- OSErr err;
- long response;
- Point where;
- SFReply oldReply;
- long procID;
- FInfo fndrInfo;
-
- /* Use new PutFile if available */
- if (gStandardFile58) {
- StandardPutFile(prompt, defaultName, reply);
- return;
- }
-
- /* Must use old PutFile */
- CenterDialog(putDlgID, &where);
- SFPutFile(where, prompt, defaultName, 0, &oldReply);
-
- /* Convert the old reply to a new reply */
- reply->sfGood = oldReply.good;
- if (!reply->sfGood)
- return;
-
- /* Convert working directory into volume reference and directory ID */
- err = GetWDInfo(oldReply.vRefNum, &reply->sfFile.vRefNum, &reply->sfFile.parID, &procID);
- if (err != noErr) {
- reply->sfFile.vRefNum = oldReply.vRefNum;
- reply->sfFile.parID = 0;
- }
-
- COPY(reply->sfFile.name, oldReply.fName);
-
- reply->sfScript = smSystemScript;
-
- err = HGetFInfo(reply->sfFile.vRefNum, reply->sfFile.parID, reply->sfFile.name, &fndrInfo);
- reply->sfReplacing = (err != fnfErr);
- reply->sfIsFolder = FALSE;
- reply->sfIsVolume = FALSE;
- }
-
-
- /* Process a menu selection. This may be from pulling down the menu, or a command-key. */
- LOCAL void
- DoMenu (menuResult)
- long menuResult;
- {
- short menuID, itemID;
- Str255 AccessoryName;
- WindowPtr savePort;
- StandardFileReply sfReply;
- SFTypeList typeList;
-
- menuID = HiWord(menuResult);
- itemID = LoWord(menuResult);
- switch (menuID) {
- case APPLE_ID:
- if (itemID == APPLE_ABOUT)
- DoAboutBox();
- else {
- GetPort(&savePort);
- GetItem(gMenu[APPLE_M], itemID, AccessoryName);
- OpenDeskAcc(AccessoryName);
- DrawMenuBar();
- SetPort(savePort);
- }
- break;
-
- case FILE_ID:
- switch (itemID) {
- case FILE_OPEN:
- gAbort = FALSE;
-
- if ((**gPrefs).show_all)
- GetFile(NULL, -1, typeList, &sfReply);
- else
- GetFile(NULL, gTypeListCount, gTypeList, &sfReply);
-
- HiliteMenu(0);
- if (sfReply.sfGood) {
- gDirChanged = TRUE;
- process_a_dropped_file(sfReply.sfFile);
- }
- break;
-
- case FILE_ABORT:
- gAbort = TRUE;
- HiliteMenu(0);
- longjmp(longjmp_data, LONGJMP_ABORT);
- break;
-
- case FILE_PREFS:
- display_prefs_dialog();
- break;
-
- case FILE_QUIT:
- gDone = TRUE;
- gAbort = TRUE;
- HiliteMenu(0);
- if (gProcessing)
- longjmp(longjmp_data, LONGJMP_ABORT);
- break;
- }
- break;
-
- case EDIT_ID:
- switch (itemID) {
- case EDIT_UNDO:
- case EDIT_CUT:
- case EDIT_COPY:
- case EDIT_PASTE:
- case EDIT_CLEAR:
- if (!SystemEdit(itemID-1)) {
- }
- break;
- }
- }
- HiliteMenu(0);
- }
-
-
- /* The user is about to perform a menu action. Enable/disable items first. */
- LOCAL void
- UpdateMenuBar ()
- {
- if (gProcessing)
- EnableItem(GetMHandle(FILE_ID), FILE_ABORT);
- else
- DisableItem(GetMHandle(FILE_ID), FILE_ABORT);
- }
-
-
- /* Process an event. You know, the normal stuff. */
- LOCAL void
- HandleEvent (Event)
- EventRecord Event;
- {
- char c;
- WindowPtr mouseWindow;
- Rect r;
- short ctlVal;
- short delta;
-
- switch (Event.what) {
- case kHighLevelEvent:
- if (!gProcessing)
- AEProcessAppleEvent(&Event);
- else
- SysBeep(1);
- break;
-
- case autoKey:
- case keyDown:
- c = (char)Event.message;
- if (Event.modifiers & cmdKey) {
- UpdateMenuBar();
- DoMenu(MenuKey(c));
- } else
- SysBeep(1);
- break;
-
- case mouseDown:
- switch (FindWindow(Event.where,&mouseWindow)) {
- case inMenuBar:
- UpdateMenuBar();
- DoMenu(MenuSelect(Event.where));
- break;
- case inSysWindow:
- SystemClick(&Event,mouseWindow);
- break;
- case inDrag:
- DragWindow(mouseWindow, Event.where, &gDragRect);
- if (mouseWindow == progressMonitorWindow) {
- (**gPrefs).progressLoc = topLeft((**((WindowPeek)mouseWindow)->contRgn).rgnBBox);
- ChangedResource((Handle)gPrefs);
- }
- break;
- case inContent:
- if (mouseWindow != FrontWindow())
- SelectWindow(mouseWindow);
- else
- if (mouseWindow == progressMonitorWindow) {
- DialogPtr dialog;
- short item;
- short part;
- ControlHandle theControl;
-
- GlobalToLocal(&Event.where);
-
- /* WARNING: This stupid code assumes 1 button and 1 scroll bar */
- switch (part = FindControl(Event.where, mouseWindow, &theControl)) {
- case inButton: /* ABORT */
- if (TrackControl(theControl, Event.where, NULL))
- longjmp(longjmp_data, LONGJMP_ABORT);
- break;
-
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
- TrackControl(theControl, Event.where, scroll_action_proc);
- break;
-
- case inThumb:
- if (TrackControl(theControl, Event.where, NULL)) {
- ctlVal = GetCtlValue(theControl);
- delta = curErrLine - ctlVal;
- TEScroll(0, delta * (**errText).lineHeight, errText);
- curErrLine = ctlVal;
- }
- break;
- }
-
- }
- break;
- }
- break;
-
- case activateEvt:
- if (Event.modifiers & activeFlag) { /* ACTIVATING */
- } else { /* DEACTIVATING */
- }
- break;
-
- case osEvt:
- switch (Event.message >> 24) {
- case suspendResumeMessage:
- if (Event.message & resumeFlag) { /* RESUME EVENT */
- gInBackground = FALSE;
- if (gProcessing)
- HiliteControl(CITEMH(progressMonitorWindow,PROG_SCROLL), 0);
- } else { /* SUSPEND EVENT */
- gInBackground = TRUE;
- if (gProcessing)
- HiliteControl(CITEMH(progressMonitorWindow,PROG_SCROLL), 255);
- }
- break;
- }
- break;
-
- case updateEvt:
- BeginUpdate((WindowPtr)Event.message);
- if ((WindowPtr)Event.message == progressMonitorWindow)
- draw_progress_monitor(TRUE);
- EndUpdate((WindowPtr)Event.message);
- break;
- }
- }
-
-
- /* Process all events until a nullEvent is received. Gets all real events out of the way so that
- * we can go back to doing what we were doing
- */
- LOCAL void
- ProcessOutstandingEvents()
- {
- EventRecord theEvent;
- long waitTime;
- Boolean event;
-
- if (gInBackground)
- waitTime = 6;
- else
- waitTime = 0;
-
- do {
- if (gWaitNextEvent)
- event = WaitNextEvent(everyEvent, &theEvent, waitTime, 0L);
- else {
- SystemTask();
- event = GetNextEvent(everyEvent, &theEvent);
- }
-
- if (event)
- HandleEvent(theEvent);
- } while (event);
- }
-
-
- /*
- * Main event loop...
- */
- void
- main (void)
- {
- EventRecord curEvent;
-
- if (AppInit())
- while (!gDone) {
- if (WaitNextEvent(everyEvent,&curEvent,15L,0L))
- HandleEvent(curEvent);
- }
- ExitToShell();
- }